package com.gopay.bis.spdb.adpay.operation;

import org.apache.commons.lang3.StringUtils;

import com.gopay.common.domain.bank.spdb.adpay.SpdbAdPayBody;
import com.gopay.common.domain.bank.spdb.adpay.SpdbAdPayHeader;
import com.gopay.common.domain.bank.spdb.adpay.SpdbAdPayMessage;
import com.gopay.common.domain.bank.spdb.adpay.res.SignInRes;
import com.gopay.common.domain.bank.spdb.adpay.res.SinCutQueryRes;
import com.gopay.common.domain.bank.spdb.adpay.res.SinCutRes;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * 
 * @Description xml-bean转换
 * @date 2016年11月2日
 * @author jiangxiangjiao
 *
 */
@SuppressWarnings("all")
public class XmlBeanUtil {
	
	// 去掉多一个下划线的问题
	//private static XStream xstream;
	
	private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
	public static final String CDATA_START = "<![CDATA[";
	public static final String CDATA_END = "]]>";
	public static final String BODY_START = "<Body>";
	public static final String BODY_END = "</Body>";
	public static final String BODY_END_ALONE = "<Body/>";
	
	private XmlBeanUtil(){
		
	}

	/**
	 * 将JAVA对象转换成请求的XML报文
	 * @param obj 被转换的java对象
	 * @param infoCla Body类中的info成员变量的实际类型
	 */
	public static <T> String toXml(Object obj,Class<T> infoCla) {
		XStream xstream = new XStream(new DomDriver("UTF-8", new NoNameCoder()));
		xstream.autodetectAnnotations(true);  
		xstream.processAnnotations(obj.getClass());
		//xstream.addDefaultImplementation(infoCla, Object.class);
		return XML_HEADER + xstream.toXML(obj);
	}
	
	/**
	 * 将AdPayTransMsg对象转换成请求的XML报文
	 * @param obj 被转换的AdPayTransMsg对象
	 * @param encryptMsg info的xml报文加密后的字符串
	 */
	public static String SpdbAdPayMessageToXml(SpdbAdPayMessage obj,String encryptMsg) {
		String xmlString = "";
		XStream xstream = new XStream(new DomDriver("UTF-8", new NoNameCoder()));
		xstream.processAnnotations(SpdbAdPayMessage.class);
		xstream.autodetectAnnotations(true);
		xstream.aliasSystemAttribute(null, "class"); // 去掉 class 属性
		if(obj.getBody() == null){
			String head = CDATA_START + CDATA_END;
			obj.setBody(new SpdbAdPayBody());
			String xml = XML_HEADER + xstream.toXML(obj).replaceAll("\n", "").replaceAll("\r", "").replaceAll(" ", "");
			xmlString =  xml.replaceFirst(BODY_END_ALONE, BODY_START+head+BODY_END);
		}else{
			obj.setBody(new SpdbAdPayBody());
			String xml = XML_HEADER + xstream.toXML(obj).replaceAll("\n", "").replaceAll("\r", "").replaceAll(" ", "");
			xmlString = xml.replaceFirst(BODY_END_ALONE, BODY_START + appendCdata(encryptMsg) + BODY_END);
		}
		return xmlString;
	}
	

	/**
	 * 将响应报文转换成AdPayTransMsg对象
	 * @param xmlStr
	 * @return AdPayTransMsg
	 */
	public static SpdbAdPayMessage<String> toSpdbAdPayMessage(String xmlStr) {
		XStream xstream = new XStream(new DomDriver("UTF-8", new NoNameCoder()));
		xstream.processAnnotations(SpdbAdPayMessage.class);
		xstream.addDefaultImplementation(String.class, Object.class);
		SpdbAdPayMessage<String> obj = (SpdbAdPayMessage<String>) xstream.fromXML(xmlStr);
		return obj;
	}
	
	/**
	 * 去掉xml中的CATA节
	 * @param xml
	 */
	public static String trimCdata(String xml){
		return StringUtils.substringBetween(xml, CDATA_START, CDATA_END);
	}
	
	/**
	 * 用CATA节包裹字符串
	 * @param str
	 */
	public static String appendCdata(String str){
		StringBuffer sb = new StringBuffer(); 
		sb.append(CDATA_START);
		sb.append(str);
		sb.append(CDATA_END);
		return sb.toString();
	}
	
	/**
	 * 将响应报文中的<INFO></INFO>部分转换成INFO对应的对象
	 * @param xmlStr
	 * @param toCla xmlStr被转换成的class类型
	 * @return T xmlStr被转换后的实例对象
	 */
	public static <T> T toBean(String xmlStr, Class<T> toCla) {
		XStream xstream = new XStream(new DomDriver("UTF-8", new NoNameCoder()));
		xstream.autodetectAnnotations(true);
		xstream.processAnnotations(toCla);
		xstream.setClassLoader(toCla.getClassLoader());
		T obj = (T) xstream.fromXML(xmlStr);
		return obj;
	}
	
	public static void main(String[] args) {
		//String str ="<?xml version=\"1.0\" encoding=\"UTF-8\"?><INFO><RespDate>20170727</RespDate><RespTransID>2017072700000272271</RespTransID><RespCode>00</RespCode><RespDesc>交易成功</RespDesc><RealTransAmount>0.01</RealTransAmount><RealEnterAmount></RealEnterAmount><RealEnterDateTime></RealEnterDateTime><FeeAmount></FeeAmount></INFO> ";
		//SignInRes info = XmlBeanUtil.toBean(str, SignInRes.class);
		String xml ="<?xml version=\"1.0\" encoding=\"UTF-8\"?><STPContext><Header><ActionCode>1</ActionCode><Activity"+
"Code>SinCutQuery</ActivityCode><ReqChannelNo>02</ReqChannelNo><ReqMerchantNo>9900000241</ReqMerchantNo><ReqDateTime>20170913051000251</ReqDateTime><ReqSysID>20170913rUBzK2nO</ReqSysID><RespCode>00"+
"</RespCode><RespDesc>交易受理成功</RespDesc><RespSysID>2017092561709280101306971188</RespSysID><RespDateTime>201709256170928010</RespDateTime></Header><Body><![CDATA[j50cpWogXy8j5dC0WryohLF3bJGo2w"+
"vm5woXu8Twb6YWEssTYHgtWbZSB2OyNC9BOrY6VTDha2A0TuuUy62LAfaEb43QE3DBYIFRup8xwa0FLslBd4RfmqT2bd96ddWSPCxJdoacyhaGCFbaF+o2XNEAEXmGQWtjuy55EIBbh0jUpLGps57E7l7jwCrPF+MtTC+leTA0sgeK62ifHRBr31eMKF8xkUj8x2"+
"m6X21DtaX0f5DqfErq5sguEO6yB+hQJkO6VfNgkrVyBP2DoyXPaFfyfpWnnQ1FtWuhfcacwUm3P9rTqJG9Ng/REQCIrEXG8V3sc7kP2x34se6PEZOuz46xgnIF0f4/p23ovD/Y8lTWKTxcOeNivP2kmSfnzz0mEQW7J1K2LQ1LahXAwOG4+NJr78xUjYXEPpUXCC"+
"9xeXBB+aFCWnkTrU7+UBZcox/sL4Ob8/M/qSadc+TUJQVYH2bv0W0Rm61jdMx06yoUMeOCHaf7KYF79CSokLZmkR4fZUjFdJMbMUuDPx8Vqx/rcA9kWV4673+2J9Egh0W1OjupdIWaftyEukre5IDb+triyuvlb+Oio+hK4DbE168gWOyiFZYQiO4YSxkXJDc7va"+
"a7ZBJX8biRY2bu/0s55PNyjnPLjgRCUhQ5j8rj36hEq7pMe+izZa1OnOpkW6/t4RanSmMEZQgZNYQOKl9C2WOO3d+aE4B+jNG6bqdGaMo2Evq4DgdFqJdCC1IDiAkJhkNbuohNpI49UpLBy6d2j/7zGFygC+Tl5asORt58BHIXMOE+4mMOb0z9+kMdLsPUJExOzG"+
"IbXHhHvLodgeGvTz8ARFpKg0BwKZXsLTNURFWTcTkI0nq1IRZBymhjONCsLooHYZ3vgvtxcm1Q1s9zjLPi]]></Body></STPContext> ";
		SpdbAdPayMessage<String> result = XmlBeanUtil.toSpdbAdPayMessage(xml);
		System.out.println(result.getHeader().getRespDesc());
		/*String str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><INFO><KeyValue>JhDGAnrIpSRYgbWuozjJfkVb8XcPyoiYZS2RAXUoaDT9Ut1Su0w3QbhP470+sHlt8wtOq5jcOyjq/Id69bDTdGTbssQoCHKnWMFSx0VzLIZRLXbCPwdsv4+cDcv0QthhClD7e1UEGam+sj4wamNwaggsnvktDandKKbY+FcfOLM=</KeyValue></INFO>";
		SignInRes info = XmlBeanUtil.toBean(str, SignInRes.class);
		
		System.out.println(info.getKeyValue());*/
		
		/*SpdbAdPayBody <String> body = new SpdbAdPayBody<String>();
		 SpdbAdPayHeader header = new SpdbAdPayHeader();
	        header.setActionCode("0");
	        header.setActivityCode("aa");
		
	    SpdbAdPayMessage<SpdbAdPayBody<String>> reqMsg = new SpdbAdPayMessage<SpdbAdPayBody<String>>();
	    reqMsg.setBody(body);
	    reqMsg.setHeader(header);
		String req = XmlBeanUtil.SpdbAdPayMessageToXml(reqMsg, "aaaaa");
		System.out.println(req);*/
	}
}
